package com.xm.controller;

import com.xm.common.ThreadPool;
import com.xm.common.constant.CommonConstant;
import com.xm.common.limit.AccessLimit;
import com.xm.entity.UserTaskInfo;
import com.xm.service.impl.BuyXmGoodServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.lang.management.ManagementFactory;
import java.nio.channels.FileChannel;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @Author tianqin
 * @Date 2024/7/31 15:00
 * 线程控制器
 */
@RestController
@CrossOrigin
public class ThreadController {

    @Resource
    private BuyXmGoodServiceImpl buyXmGoodService;

    /**
     * 遍历当前线程组及其子线程组，找到并中断指定前缀名称的线程
     */
    @GetMapping("/shutDownThread")
    public void shutDownThread() throws IOException {

        // 获取当前线程组及其子线程组中的所有线程
        ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
        while (rootGroup.getParent()!= null) {
            rootGroup = rootGroup.getParent();
        }

        // 用于存储线程对象
        Map<String, Thread> threadMap = new ConcurrentHashMap<>();
        traverseThreads(rootGroup, threadMap);
        Set<String> threadNames = threadMap.keySet();
        for (String threadName : threadNames) {
            if (threadName.startsWith("http-nio-7779-exec")) {
                Thread thread = threadMap.get(threadName);
                if (thread!= null && thread.isAlive()) {
                    thread.interrupt();
                }
            }
        }
        // 清空日志内容
        cleanLogFile();

    }


    private static void cleanLogFile() throws IOException {

        // 输出新的内容到目标文件
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(CommonConstant.FILE_PATH))) {
            writer.write("文件内容已被清空~");
        }
        System.out.println("文件内容已被清空~");
    }

    /**
     * 获取正在运行的线程数
     * @return
     */
    @GetMapping("/getRunningThreadCount")
    @AccessLimit(times = 10, timeUnit = TimeUnit.SECONDS, maxCount = 5, preKey = "getThread", msg = "服务请求达到最大限制，请求被拒绝！")
    public Map<String,Integer> getRunningThreadCount(){
        int count = Optional.ofNullable(buyXmGoodService.getAllUserRunningTask())
                .map(Map::values)
                .stream()
                .flatMap(Collection::stream)
                .mapToInt(Set::size)
                .sum();
        Map<String,Integer> resultMap = new HashMap<>();
        resultMap.put("buyOrderThread",count);
        return resultMap;
    }

    @GetMapping("/getRunningTasks")
    public ResponseEntity<Map<String, Set<UserTaskInfo>>> getRunningTasks() {
        return ResponseEntity.ok(buyXmGoodService.getAllUserRunningTask());
    }

    @GetMapping("/status/{userName}")
    public ResponseEntity<Set<UserTaskInfo>> getTaskStatus(@PathVariable String userName) {
        Set<UserTaskInfo> taskInfo = buyXmGoodService.getAllUserRunningTask().get(userName);
        if (taskInfo != null) {
            return ResponseEntity.ok(taskInfo);
        }
        return ResponseEntity.notFound().build();
    }
    // TODO:后期删除map
    @GetMapping("/cancelTaskByName")
    public ResponseEntity<String> cancelTaskByName(String userName ,String taskId) {
        boolean b = ThreadPool.interruptThreadByName(taskId);
        if (b) {
            return ResponseEntity.ok("200");
        }
        return ResponseEntity.ok("500");
    }


    public static void traverseThreads(ThreadGroup group, Map<String, Thread> threadMap) {
        int activeCount = group.activeCount();
        Thread[] threads = new Thread[activeCount];
        group.enumerate(threads, false);

        for (Thread thread : threads) {
            if (thread!= null) {
                threadMap.put(thread.getName(), thread);
            }
        }

        int groupCount = group.activeGroupCount();
        ThreadGroup[] groups = new ThreadGroup[groupCount];
        group.enumerate(groups, false);

        for (ThreadGroup subGroup : groups) {
            traverseThreads(subGroup, threadMap);
        }
    }

}

